package com.fingard.avatar.website.config;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.fingard.avatar.website.model.bean.ResultContext;
import com.fingard.avatar.website.model.enums.ResultCode;
import com.fingard.avatar.website.model.po.SysUserPo;
import com.fingard.avatar.website.service.UserAuthService;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.security.Principal;

/**
 * @author 徐一涛
 * @date 2022/4/26
 */
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {

    public static String SPRING_SESSION_COOKIE_NAME = "SESSION";
    public static String AVATAR_TOKEN_HEADER_NAME = "token";

    protected UserAuthService userAuthService;
    public AuthenticationInterceptor(UserAuthService service) {
       this.userAuthService = service;
    }

    @Override
    public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
                             @NonNull Object handler) {
        try {
            String token = getToken(request);
            if (StrUtil.isNotEmpty(token)) {
                SysUserPo user = userAuthService.getUser(token);
                if (ObjectUtil.isNotNull(user)) {
                    String uri = request.getRequestURI();
                    if(userAuthService.checkPermission(user.getUserName(), uri, request.getMethod())) {
                        UserContext.setUser(user);
                        return true;
                    } else {
                        log.info("user:{}  path:{}  权限不足", user.getUserName(), uri);
                        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
                        response.setContentType(ContentType.JSON.getValue());
                        response.getWriter().write(JSONUtil.toJsonStr(ResultContext.fail(ResultCode.WITHOUT_RIGHT, "权限不足")));
                        return false;
                    }
                }
            }
//            response.sendRedirect(request.getContextPath() + "login");
            response.sendError(HttpStatus.HTTP_UNAUTHORIZED,
                    JSONUtil.toJsonStr(ResultContext.fail(ResultCode.NOT_LOG_IN, "未登录，请先登录")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void postHandle(@NonNull HttpServletRequest request,@NonNull HttpServletResponse response,
                           @NonNull Object handler, ModelAndView modelAndView) {
    }

    @Override
    public void afterCompletion(@NonNull HttpServletRequest request,@NonNull HttpServletResponse response,
                                @NonNull Object handler, Exception ex) {
        UserContext.remove();
    }

    private String getToken(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (StrUtil.equals(cookie.getName(), SPRING_SESSION_COOKIE_NAME)) {
                    return cookie.getValue();
                }
            }
        }

        return request.getHeader(AVATAR_TOKEN_HEADER_NAME);
    }

}
